package com.ysh.web.controller.store;

import com.github.pagehelper.PageInfo;
import com.ysh.domain.store.Catalog;
import com.ysh.domain.store.Company;
import com.ysh.domain.store.Question;
import com.ysh.utils.BeanUtil;
import com.ysh.web.controller.BaseServlet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;


@WebServlet("/store/question")
public class QuestionServlet extends BaseServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取参数
        String operation = req.getParameter("operation");
        // 获取页面页码
        if ("list".equals(operation)){
            list(req, resp);
        }else if ("toAdd".equals(operation)){
            toAdd(req,resp);
        }else if ("save".equals(operation)){
            try {
                save(req,resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if ("toEdit".equals(operation)){
            toEdit(req,resp);
        }else if ("edit".equals(operation)){
            try {
                edit(req,resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if ("delete".equals(operation)){
            delete(req,resp);
        }else if ("toTestUpload".equals(operation)){
            toTestUpload(req,resp);
        }else if ("testUpload".equals(operation)){
            try {
                testUpload(req,resp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else if ("downloadReport".equals(operation)){
            downloadReport(req,resp);
        }

    }

    /*
        删除操作
     */
    private void delete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取前台id
        // 将数据获取到，并封装成一个对象
        Question question = BeanUtil.fillBean(req,Question.class);
        // 调用业务层接口
        questionService.delete(question);

        // 跳转回页面list
        // list(req,resp);
        resp.sendRedirect(req.getContextPath()+"/store/question?operation=list");


    }


    /*
        修改操作
     */
    private void edit(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        // 封装对象，包含文件
        // 1. 确认该操作是否支持文件上传操作，enctype="multipart/form-data"必须有才支持
        if (ServletFileUpload.isMultipartContent(req)){
            // 2. 创建磁盘工厂对象
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 3. Servlet文件上传核心对象
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            // 4. 从request中读取数据
            List<FileItem> fileItems = fileUpload.parseRequest(req);

            // 创建一个标记，标记当前时候有上传文件的操作
            boolean flag = false;
            for (FileItem fileItem : fileItems) {
                if (StringUtils.isNotBlank(fileItem.getName())){
                    flag = true;
                    break;
                }
            }

            // -- 处理form表单提交的普通数据
            // 将数据获取到，封装成一个对象
            Question question = BeanUtil.fillBean(fileItems, Question.class);
            // 调用业务层接口
            /*
                解决文件没存进、重名问题
                思路：通过返回的id值作为图片名称
             */
            questionService.update(question,flag);



            // -- 处理form表单提交过来的文件数据
            for (FileItem fileItem : fileItems) {
                // 5. 当前表单是否是文件表单 type="file",
                if (!fileItem.isFormField()){ // true：非文件字段
                    // 6. 从临时存储文件的地方将内容写入到指定位置(webApp下的upload文件夹下)
                    fileItem.write(new File(this.getServletContext().getRealPath("upload"),question.getId()));
                }
            }
        }


        // 跳转回页面list
        // list(req,resp);
        resp.sendRedirect(req.getContextPath()+"/store/question?operation=list");
    }

    /*
        跳转到修改页面,并带入数据
        根据id查询信息，并将结果带入页面中进行回显
     */
    private void toEdit(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 查询要修改的数据findById
        String id = req.getParameter("id");
        // 根据id查询结果
        Question question = questionService.findById(id);
        // 将数据加载到指定区域，供页面获取
        req.setAttribute("question",question);

        // 找到题目对应企业的信息列表
        List<Company> companyList = companyService.findAll();
        // 题目所属类别/所属学科列表
        List<Catalog> catalogList = catalogService.findAll();

        // 存入request域对象中
        req.setAttribute("companyList",companyList);
        req.setAttribute("catalogList",catalogList);

        // 存储转发到update.jsp页面
        req.getRequestDispatcher("/WEB-INF/pages/store/question/update.jsp").forward(req,resp);
    }

    /*
        添加操作
     */
    private void save(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        // 封装对象，包含文件
        // 1. 确认该操作是否支持文件上传操作，enctype="multipart/form-data"必须有才支持
        if (ServletFileUpload.isMultipartContent(req)){
            // 2. 创建磁盘工厂对象
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 3. Servlet文件上传核心对象
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            // 4. 从request中读取数据
            List<FileItem> fileItems = fileUpload.parseRequest(req);

            // 创建一个标记位，标记当前是否有上传文件的操作
            boolean flag = false;
            for (FileItem item : fileItems){
                if (StringUtils.isNotBlank(item.getName())){
                    flag = true;
                    break;
                }
            }

             // if (true) return;

            // -- 处理form表单提交的普通数据
            // 将数据获取到，封装成一个对象
            Question question = BeanUtil.fillBean(fileItems, Question.class);
            // 调用业务层接口
            /*
                解决文件没存进、重名问题
                思路：通过返回的id值作为图片名称
             */
            String picture = questionService.save(question,flag);

            // -- 处理form表单提交过来的文件数据
            for (FileItem fileItem : fileItems) {
                // 5. 当前表单是否是文件表单 type="file",
                if (!fileItem.isFormField()){ // true：非文件字段
                    // 6. 从临时存储文件的地方将内容写入到指定位置(webApp下的upload文件夹下)
                    fileItem.write(new File(this.getServletContext().getRealPath("upload"),picture));
                }
            }
        }

        /*
            小技巧
         */
        // if(true)return;    // 暂时忽略后面的代码执行，欺骗编译器，从而进行快速调试

        // 跳转回页面list
        // list(req,resp);
        resp.sendRedirect(req.getContextPath()+"/store/question?operation=list");
    }

    /*
        跳转到添加页面
     */
    private void toAdd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 找到题目对应企业的信息列表
        List<Company> companyList = companyService.findAll();
        // 题目所属类别/所属学科列表
        List<Catalog> catalogList = catalogService.findAll();

        // 存入request域对象中
        req.setAttribute("companyList",companyList);
        req.setAttribute("catalogList",catalogList);


        // 跳转页面
        req.getRequestDispatcher("/WEB-INF/pages/store/question/add.jsp").forward(req,resp);

    }

    private void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 进入列表页
        // 获取数据
        // 默认设置，当前页1
        int page = 1;
        // 默认设置，每页条数30
        int size = 30;
        // 判断页面是否获取值，有值，按页面参数进行分页
        // 当前页面
        if (StringUtils.isNotBlank(req.getParameter("page"))){
            page = Integer.parseInt(req.getParameter("page"));
        }
        // 每页显示数据条数
        if (StringUtils.isNoneBlank(req.getParameter("size"))){
            page = Integer.parseInt(req.getParameter("size"));
        }
        // 指定参数进行分页查询
        PageInfo all = questionService.findAll(page, size);
        // 将数据保存到指定的位置
        req.setAttribute("page",all);
        // 跳转页面
        req.getRequestDispatcher("/WEB-INF/pages/store/question/list.jsp").forward(req,resp);
    }

    /*
        文件上传功能
     */
    // 跳转文件上传页面
    private void toTestUpload(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 跳转页面
        req.getRequestDispatcher("/WEB-INF/pages/store/question/testFileUpload.jsp").forward(req,resp);

    }
    // 上传文件操作
    private void testUpload(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        // 1. 确认该操作是否支持文件上传操作，enctype="multipart/form-data"必须有才支持
        if (ServletFileUpload.isMultipartContent(req)){
            // 2. 创建磁盘工厂对象
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 工厂可以设置一些东西
            // File repository = factory.getRepository();
            // 3. Servlet文件上传核心对象
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            // 4. 从request中读取数据
            List<FileItem> fileItems = fileUpload.parseRequest(req);

            for (FileItem fileItem : fileItems) {
                // System.out.println(fileItem.getName()); // blog.jpg
                // 5. 当前表单是否是文件表单 type="file",
                if (!fileItem.isFormField()){ // true：非文件字段
                    // 6. 从临时存储文件的地方将内容写入到指定位置(webApp下的upload文件夹下)
                    fileItem.write(new File(this.getServletContext().getRealPath("upload"),fileItem.getName()));
                }
            }
        }
    }

    /*
        导出xlsx的Excel表格操作
     */
    private void downloadReport(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 设置返回的数据类型为文件xlsx类型
        // 设置请求头，指定文件类型为xlsx(从tomcat的conf下的web.xml中搜索xlsx对应的值)
        // 指定文件的字符集为UTF-8
        resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        // 定义中文的文件名称
        String fileName = new String("在线题库.xlsx".getBytes(),"ISO-8859-1");
        // 设置响应头
        resp.addHeader("Content-Disposition","attachment;fileName="+fileName);


         // 生成报告的文件，然后传递到前端页面
        ByteArrayOutputStream os = questionService.downloadReport();
        // 获取产生响应的流对象
        ServletOutputStream sos = resp.getOutputStream();
        // 将数据从原始的字节流对象中提取出来写入到servlet对应的输出流中
        os.writeTo(sos);
        // 将输出流刷新
        sos.flush();
        // 释放资源
        sos.close();
        os.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
